﻿#include "widget.h"
#include "ui_widget.h"

int cnt = 0;

const uint TotalSize = 1843200;
volatile uint rest_size = 0;
volatile int read_continue = 0;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_login.show();
    auto f = [&](){
        this->show();
    };
    m_ptrSql = Sqlite::getIntance();
    m_ptrSql->init();
    connect(&m_login, &Login::sendLoginSuccess, this, f);

    socket = new QTcpSocket;  //创建套接字
    connect(socket, &QTcpSocket::connected, [=](){//连接信号触发
        //连接成功
        qDebug() << "连接成功";
        int ret = socket->write("qt");
        if(ret < 0){
            qDebug() << "send fail";
        }
        ui->releaseButton->setEnabled(true);
        ui->recognizeButton->setEnabled(true);
        ui->moveButton->setEnabled(true);
        ui->grabButton->setEnabled(true);
        ui->connectButton->setText("断开连接");
        ui->connectButton->setStyleSheet("background-color:rgb(0,170, 0);"
                                         "color: rgb(255, 255, 255);");
    });
    connect(socket, &QTcpSocket::disconnected, [=](){//断开信号触发
        ui->releaseButton->setEnabled(false);
        ui->recognizeButton->setEnabled(false);
        ui->moveButton->setEnabled(false);
        ui->grabButton->setEnabled(false);
        ui->connectButton->setText("连接");
        ui->connectButton->setStyleSheet("background-color: rgb(255, 0, 0);"
                                         "color: rgb(255, 255, 255);");
        socket->close();
    });
    connect(socket, &QTcpSocket::readyRead, this, &Widget::recv_data);

    //接受图片处理后的物体位置以及物体的length、width
    connect(this,SIGNAL(posionPic(Position)),this, SLOT(handlerPicPosition(Position)));//上位机接收物体位置完成信号

    connect(this,&Widget::recvAllSuccess,this,&Widget::sendPic);//上位机图片接收完成信号
}

Widget::~Widget()
{
    delete ui;
}

void Widget::closeEvent(QCloseEvent *event)//关闭事件
{
    QMessageBox messageBox(QMessageBox::Warning, "waring", "Exit the system?", QMessageBox::Yes | QMessageBox::No);
    if (messageBox.exec() == QMessageBox::Yes) {
        event->accept();
    } else {
        event->ignore();
    }
}

int Widget::detect_picture(QString *ret){

    QProcess process;
    process.start("python ../detect_window.py"); // 启动进程
    process.waitForStarted();
    process.waitForFinished();
    QString str = QString::fromLocal8Bit(process.readAllStandardOutput());

    QString result = str.replace(QRegExp(QString("\\r\\n")), QString('-'))
            .replace(QRegExp(QString("tensor")), QString(""));

    QStringList list = result.split(QString("-"));
    QString positions_str = list.at(0);
    QRegExp rx("\\d+");

    QStringList MyList;
    int pos = 0;

    while ((pos = rx.indexIn(positions_str, pos)) != -1) {
        MyList << rx.cap(0);
        pos += rx.matchedLength();
    }

    QString cls_str = list.at(1);
    *ret = cls_str.toInt() == 1 ? "red": "blue";
    ret->append(":");
    for(QString pos: MyList){
        ret->append(":");
        ret->append(pos);
    }

    return 0;
}

void Widget::on_connectButton_clicked()
{
    QString str = ui->connectButton->text();
    if ("连接" == str) {
        QString ip = ui->ipEdit->text();
        QString port = ui->portEdit->text();
        if (ip.isEmpty() || port.isEmpty()) {
            QMessageBox::warning(nullptr, "连接", "服务器IP和Port不能为空!");
            return;
        }
        socket->abort();//取消已有连接，重置套接字
        socket->connectToHost(QHostAddress(ip), port.toUShort());//连接服务器主机地址

    } else {
        socket->close();
    }
}
/*
void Widget::recv_data()
{
    qDebug()<<"接收图片";
    if(read_continue == 0){
        rest_size = SIZE;
    }

    QFile file("1.jpg");
    if(file.open(QIODevice::ReadWrite |QIODevice::Append )){
        qDebug() << "open file success!";
    }

    uint readSize = 0;char buffer[512];

    while(1)
    {
        readSize  = socket->read(buffer, 512);
        if(readSize == 0) break;
        qDebug()<<readSize;
//        resizeTotal += readSize;
        file.write(buffer, readSize);//有就打开，没有就创建，并且写的时候追加里面的内容
        rest_size -= readSize;

        memset(buffer, 0, 512);

        if(rest_size > 0){
            read_continue = 1;
        }

        if (rest_size <= 0 && !socket->waitForReadyRead()){
            if(rest_size <= 0){
                read_continue = 0;

            }
            break;
        }
    }
    file.close();
    qDebug()<< "接收完成！";
}
*/

void Widget::recv_data()
{
    if(cnt == 0){
//        char bf[3] = {0};
//        int rev_num = socket->read(bf, 3);
        QByteArray arr = socket->read(3);
        cnt =1;
//        str = QString(bf);
        str = QString(arr);
        qDebug()<<"str:" <<str;
    }

    if("pic" ==str && cnt==1){//接收图片
//        qDebug() << "处理pic";
        if(read_continue == 0){
            rest_size = TotalSize;
        }
        QFile file("1.jpg");
        if(!file.open(QIODevice::ReadWrite |QIODevice::Append )){
            qDebug() << "open file false!";
        }
        uint readSize = 0;
        char buffer[512] ={0};
        while(1)
        {
            readSize  = socket->read(buffer, 512);
            if(readSize == 0) break;
            //        qDebug()<<readSize;

            file.write(buffer, readSize);//有就打开，没有就创建，并且写的时候追加里面的内容

            rest_size -= readSize;
            qDebug()<<rest_size;

            memset(buffer, 0, 512);

            if(rest_size > 0){
                read_continue = 1;
            }
            if ((rest_size <= 0 && !socket->waitForReadyRead(2000)) || readSize == 0){
                if(rest_size <= 0){
                    read_continue = 0;
                    cnt = 0;
                    qDebug() << "finish";
                    emit recvAllSuccess();
                    qDebug() << "emit finish";
                }
//                read_continue = 0;
//                cnt = 0;
//                emit recvAllSuccess();
                  break;
            }
        }
        //    qDebug()<< "接收完成！";
        file.close();
    }
    else if("rea" == str && cnt==1)//机械臂到位reach开始读取图片
    {
        qDebug() << "机械臂已到达指定位置";
        QMessageBox::information(nullptr,"提示","机械臂已到达指定位置");
        cnt = 0;
        return;
    }
    else if("not" == str && cnt==1){
        QMessageBox::warning(nullptr, "警告","机械臂还未到达指定位置");
        cnt = 0;
        return;
    }
}

void Widget::sendPic()//发送图片通过opencv处理
{
    QFile file("1.jpg");
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
        qDebug() << "open file false!";
        return;
    }
//    QByteArray byte = file.readAll();
//    file.close();
    ////////////////////////////////////////////////////////////////////
    QString* ret_detect = new QString();
    int ret = detect_picture(ret_detect);
    qDebug() << *ret_detect;
    QStringList detec_list = ret_detect->split(":");
    Position po;
    po.x = 0;
    po.y = 0;
    po.z = 18;
    po.ch = 'c';
    posionPic(po);
   // emit sendPicSuccess(byte, TotalSize);
    ////////////////////////////////////////////////////////////////////
    QFile::remove("1.jpg");
}

void Widget::sendPosition(Position position)
{
    //定义bit流
    QByteArray transfer;
    //使用memcpy之前分配内存空间
    transfer.resize(sizeof(position));
    //内存拷贝
    memcpy(transfer.data(),&position,sizeof(position));
    //传输比特流数
    socket->write(transfer);

}

//void Widget::control(Control control)
//{
//    //定义bit流
//    QByteArray transfer;
//    //使用memcpy之前分配内存空间
//    transfer.resize(sizeof(control));
//    //内存拷贝
//    memcpy(transfer.data(),&control,sizeof(control));
//    //传输比特流数
//    socket->write(transfer);

//}

void Widget::on_recognizeButton_clicked()//识别物体位置
{
    qDebug()<< "reconize";
    str = "read";

    socket->write(str.toLatin1());
    socket->flush();
}

void Widget::on_moveButton_clicked()//移动
{
    QString str = "write";
    socket->write(str.toLatin1());
    Position position;
    QString x =ui->movex_object->text();
    QString y =ui->movey_object->text();
    QString z =ui->movez_object->text();
    if(x.isEmpty() || y.isEmpty() || z.isEmpty() ){
        QMessageBox::information(nullptr, "提示", "请输入要移动的位置！");
        return;
    }
    position.x = x.toUInt();
    position.y = y.toUInt();
    position.z = z.toUInt();
    position.ch = 'c';//移动标志

    sendPosition(position);
}

void Widget::on_grabButton_clicked()//抓取
{
    QString str = "write";
    socket->write(str.toLatin1());
    //发送一个抓取指令
    Position position;
    QString x =ui->grabx_object->text();
    QString y =ui->graby_object->text();
    QString z =ui->grabz_object->text();
    if(x.isEmpty() || y.isEmpty() || z.isEmpty() ){
        QMessageBox::information(nullptr, "提示", "请输入要抓取的位置！");
        return;
    }
    position.ch = 'c';
    position.x = x.toUInt();
    position.y = y.toUInt();
    position.z = z.toUInt();

    sendPosition(position);
/*
    Control grab;
    grab.ch1 = 's';//身份标志's'
    grab.ch2 = '1';//抓取'1'
    grab.l = 1;
    grab.w = 1;
    control(grab);
    */
}

void Widget::on_releaseButton_clicked()//释放
{
    //发送一个释放指令
    QString str = "write";
    socket->write(str.toLatin1());
    Position position;
    QString x =ui->releasex_object->text();
    QString y =ui->releasex_object->text();
    QString z =ui->releasex_object->text();
    if(x.isEmpty() || y.isEmpty() || z.isEmpty() ){
        QMessageBox::information(nullptr, "提示", "请输入要释放的位置！");
        return;
    }
    position.ch = 's';
    position.x = x.toUInt();
    position.y = y.toUInt();
    position.z = z.toUInt();

    sendPosition(position);
   /*
    Control release;
    release.ch1 = 's';//身份标志's'
    release.ch2 = '0';//抓取'1'
    release.l = 1;
    release.w = 1;
    control(release);
    */
}


void Widget::handlerPicPosition(Position posion)//获取opencv处理后的物体位置
{
//    m_posion = posion;
    qDebug() << posion.x;
    qDebug() << posion.y;
    qDebug() << posion.z;
    QString x= QString::number(posion.x);
    QString y= QString::number(posion.y);
    QString z= QString::number(posion.z);
    ui->x_object->setText(x);
    ui->x_object->setText(y);
    ui->x_object->setText(z);
}


void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setOpacity(0.3);  //透明度
    QPixmap pixmap = QPixmap(":/pic/robot").scaled(this->size());// 加载背景图片
    painter.drawPixmap(this->rect(), pixmap);// 绘制背景图片
}


